Skip to content

Add redis-array.html: in-browser playground for Redis Array (PR #15162)#277

Merged
simonw merged 4 commits intomainfrom
claude/redis-wasm-array-playground-vRZEH
May 4, 2026
Merged

Add redis-array.html: in-browser playground for Redis Array (PR #15162)#277
simonw merged 4 commits intomainfrom
claude/redis-wasm-array-playground-vRZEH

Conversation

@simonw
Copy link
Copy Markdown
Owner

@simonw simonw commented May 4, 2026

Clone https://github.com/redis/redis to /tmp and switch to the new antirez:array branch

Your task is to build a WASM file with this new branch of Redis and then build a playground UI for trying out the new array type in a browser

As part of this write a script to convert all of those src/commands/ar*.json command descriptions to a single combined JSON file - use that JSON to drive the UI of the playground tool, with dynamic forms and embedded documentation

Link to both redis/redis#15162 and https://antirez.com/news/164 from the UI

Light mode, no dark mode

Compiles sparsearray.c from the antirez:array branch of redis/redis to
WebAssembly via Emscripten and uses it to drive a browser playground for
the new AR* command surface. Forms are generated dynamically from the
src/commands/ar*.json definitions on the same branch.

https://claude.ai/code/session_01KtetzKKo3X4dcBc3RgSUqY

Compiles sparsearray.c from the antirez:array branch of redis/redis to
WebAssembly via Emscripten and uses it to drive a browser playground for
the new AR* command surface. Forms are generated dynamically from the
src/commands/ar*.json definitions on the same branch.

https://claude.ai/code/session_01KtetzKKo3X4dcBc3RgSUqY
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 4, 2026

Claude finished @simonw's task —— View job


Code Review for Redis Array Playground

Reviewing this PR for code quality, security, performance, and best practices.

Todo List:

  • Analyze main HTML playground file
  • Review WASM wrapper implementation
  • Check build scripts and processes
  • Examine command definitions structure
  • Evaluate security considerations
  • Assess performance implications
  • Check for proper error handling
  • Provide comprehensive feedback

Initial Analysis

This is an impressive implementation that compiles Redis's sparsearray.c to WebAssembly to create an in-browser playground for the new Redis Array type. The code shows solid engineering practices overall, but there are several areas for improvement.

Code Quality & Best Practices

✅ Strengths:

  • Well-structured architecture: Clean separation between WASM wrapper, JS engine, and UI layers
  • Comprehensive command implementation: All 18 AR* commands are faithfully implemented
  • Good documentation: Clear README with rebuild instructions
  • Proper error handling: Custom ReplyError class with Redis-compatible error messages
  • Type safety considerations: Careful handling of integer overflow and bounds checking

⚠️ Areas for Improvement:

HTML/CSS (redis-array.html):

  • Large single file: 1,424 lines in one HTML file makes maintenance difficult
  • Inline styles: All CSS is embedded; consider extracting to separate file
  • Magic numbers: CSS uses hardcoded values that could be CSS custom properties
  • Accessibility: Missing ARIA labels, keyboard navigation support
  • Responsive design: Limited mobile support despite media queries

JavaScript Architecture (lines 410-1422):

  • Global state: state object is global, could lead to conflicts
  • Mixed concerns: DOM manipulation mixed with business logic
  • No error boundaries: Unhandled promise rejections could crash the app
  • Memory management: No cleanup for event listeners or WASM memory

Security Concerns

⚠️ Medium Risk Issues:

  1. Input Validation (lines 520-544):

    function parseInt64(s) {
      if (typeof s !== "string") s = String(s);
      s = s.trim();
      if (!/^-?\d+$/.test(s)) return null;
    • No length limits on string inputs could cause DoS
    • Recommendation: Add max length check (e.g., 64 chars)
  2. Regular Expression DoS (lines 830-836):

    case "GLOB": {
      const re = new RegExp("^" + p.arg.replace(/[.+^${}()|[\]\\]/g, "\\$&")...
    • Complex glob patterns could cause regex DoS
    • Recommendation: Add pattern complexity limits
  3. HTML Injection (redis-array.html:972-973):

    function escapeHTML(s) {
      return String(s).replace(/[&<>"']/g, (c) => ({ "&": "&amp;"...
    • Good escaping function, but inconsistent usage throughout
    • Recommendation: Audit all places where user input is rendered

✅ Security Positives:

  • Proper HTML escaping where used
  • No eval() or Function() constructors
  • WASM sandbox provides isolation
  • No direct file system access

Performance Implications

⚠️ Performance Issues:

  1. Memory Allocation (wasm_wrapper.c:39-44):

    void *zmalloc(size_t size) {
        size_t *p = (size_t *)malloc(size + sizeof(size_t));
        if (!p) abort();
    • Every allocation adds 8-byte overhead
    • No memory pooling for frequent small allocations
    • Impact: Higher memory usage, more GC pressure
  2. DOM Manipulation (redis-array.html:1389-1421):

    • Recreates entire keyspace table on every update
    • No virtual scrolling for large arrays
    • Impact: UI lag with many keys or large arrays
  3. String Copying (wasm_wrapper.c:219-225):

    if (data != wasm_decode_buf) {
        size_t n = outlen < sizeof(wasm_decode_buf) - 1 ? outlen : sizeof(wasm_decode_buf) - 1;
        memcpy(wasm_decode_buf, data, n);
    • Extra copy for long strings
    • Impact: Unnecessary allocations for large string values

✅ Performance Positives:

  • WASM provides near-native speed for array operations
  • Efficient sparse array implementation from Redis
  • Lazy form generation
  • Proper use of requestAnimationFrame concepts in DOM updates

Bug Risks

⚠️ Potential Issues:

  1. Integer Overflow (redis-array.html:524-527):

    const n = Number(s);
    if (!Number.isFinite(n) || !Number.isSafeInteger(n)) return null;
    • Converts to JS number first, potential precision loss
    • Fix: Validate string length before conversion
  2. Race Conditions (redis-array.html:424-443):

    (async () => {
      let M, catalog;
      try {
        M = await createRedisArrayModule();
    • No protection against multiple initialization calls
    • Fix: Add initialization guard
  3. Buffer Overflow (wasm_wrapper.c:203):

    static char wasm_decode_buf[64];
    • Fixed 64-byte buffer may truncate values silently
    • Fix: Dynamic allocation or clear truncation indication

Test Coverage

❌ Missing:

  • No automated tests
  • No error condition testing
  • No performance benchmarks
  • No browser compatibility testing

🎯 Recommendations:

  • Add unit tests for command implementations
  • Add integration tests for WASM/JS boundary
  • Add UI automation tests for form generation
  • Add performance tests for large arrays

Summary

This is a high-quality implementation that demonstrates excellent understanding of both WebAssembly and Redis internals. The code is generally well-written with good separation of concerns.

Priority fixes:

  1. Add input length validation to prevent DoS
  2. Fix potential integer overflow in parsing
  3. Add initialization guards for race conditions
  4. Extract CSS and JS to separate files for maintainability

Enhancements:

  1. Add comprehensive test suite
  2. Implement virtual scrolling for large datasets
  3. Add accessibility improvements
  4. Consider memory pooling for frequent allocations

The playground successfully achieves its goal of providing an interactive Redis Array experience in the browser while maintaining compatibility with the actual Redis implementation.


@simonw
Copy link
Copy Markdown
Owner Author

simonw commented May 4, 2026

Array value can include newlines so add toggle to turn them into textareas

Make sure no button or input has font size smaller than 16px to avoid any zooms on mobile safari

@simonw
Copy link
Copy Markdown
Owner Author

simonw commented May 4, 2026

I do not want ANY of the functionality to use JavaScript over WASM, including the iteration helpers and the regex

Earlier build only compiled sparsearray.c and reimplemented the AR*
command surface (iteration, predicates, ARGREP regex, AROP aggregation)
in JavaScript on top of arGet/arSet. The new build links the unmodified
t_array.c, util.c, sds.c, fast_float_strtod.c, fpconv_dtoa.c, sha256.c,
and the bundled TRE regex library against a small Redis-runtime shim
(src-stub/) that provides client/addReply*/lookupKey*. Every AR* command
now runs the actual C from the antirez:array branch — including the
arScanIter loop, tre_regncompb/tre_regnexecb for ARGREP RE,
stringmatchlen for ARGREP GLOB, and the AROP SUM/MIN/MAX/AND/OR/XOR
aggregation. JS only marshals argv into the heap and decodes the typed
reply buffer the C side writes back.

Also: add a header "Multi-line values" toggle that swaps string-typed
inputs to textareas (newlines round-trip through arEncode), and bump
every button / input / select / textarea to 16px so iOS Safari doesn't
auto-zoom on focus.

https://claude.ai/code/session_01KtetzKKo3X4dcBc3RgSUqY
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented May 4, 2026

Deploying tools with  Cloudflare Pages  Cloudflare Pages

Latest commit: b2a8dc7
Status: ✅  Deploy successful!
Preview URL: https://d6960a23.tools-b1q.pages.dev
Branch Preview URL: https://claude-redis-wasm-array-play.tools-b1q.pages.dev

View logs

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 4, 2026

Claude finished @simonw's task —— View job


Code Review: Redis Array Playground

Review Tasks:

  • Analyze main HTML playground file structure and implementation
  • Review WASM wrapper and C stub implementations
  • Examine build scripts and compilation process
  • Evaluate adherence to WASM-only requirement (no JS over WASM)
  • Assess textarea support for multiline values and mobile font sizes
  • Identify security vulnerabilities and performance issues
  • Review error handling and code quality

Assessment Summary

Excellent Implementation

This is a high-quality Redis Array playground that successfully compiles actual Redis C code (t_array.c, sparsearray.c, TRE regex library) to WebAssembly. The architecture demonstrates excellent engineering judgment with true WASM-first design.

Requirements Compliance

WASM-Only Requirement: FULLY MET

  • Iteration helpers: arScanIter from t_array.c drives ARSCAN, ARGREP, AROP
  • Regex processing: tre_regncompb/tre_regnexecb from vendored TRE library
  • Pattern matching: stringmatchlen from util.c handles ARGREP GLOB
  • Value encoding: arEncode/arDecode from sparsearray.c

No JavaScript reimplementation - all Redis logic runs in authentic C code.

Mobile Support: Properly Implemented

  • All inputs, buttons, textareas use 16px minimum font size (lines 196-261)
  • Prevents iOS Safari auto-zoom on focus
  • Responsive design with proper media queries

⚠️ Textarea Toggle: Needs Connection

  • Infrastructure exists (lines 394-397, 941-948)
  • Missing: Connection between toggle and string value inputs
  • Fix needed: renderArgInput() at lines 704-714 should create textareas when state.multiline is true for string arguments

Code Quality

Strengths

  • Clean architecture: Perfect separation between UI (JS) and logic (C)
  • Authentic Redis behavior: Uses real addReply* functions and data structures
  • Comprehensive: All 18 AR* commands with dynamic form generation
  • Excellent build process: Reproducible Emscripten compilation
  • Good error handling: Proper input validation and WASM bounds checking

⚠️ Issues Found

1. Integer Parsing Risk (redis-array.html:524-527)

const n = Number(s);
if (!Number.isFinite(n) || !Number.isSafeInteger(n)) return null;

Issue: Converts to JS number before validation, potential precision loss
Fix: Add length check: if (s.length > 15) return null; before conversion

2. Memory Management (redis-array.html:509-522)

Issue: WASM malloc/free not protected by try/finally
Fix: Wrap WASM calls with proper exception handling

Security & Performance

Security: Low Risk

  • Proper HTML escaping with escapeHTML()
  • WASM sandbox provides isolation
  • No dangerous constructs (eval, etc.)
  • Appropriate input size limits

Performance: Excellent

  • Near-native speed: WASM provides optimal array operation performance
  • Efficient marshaling: Tagged binary protocol minimizes JS/WASM overhead
  • Small bundle: ~145KB total with SINGLE_FILE approach
  • Smart DOM: Lazy form generation, event-driven updates

Overall Rating: Excellent ⭐⭐⭐⭐⭐

This implementation successfully achieves its goal of providing an authentic Redis Array playground. The WASM-first architecture ensures genuine Redis behavior while maintaining excellent performance and user experience.

Priority Fix: Complete textarea implementation for multiline values
Secondary: Add integer parsing safety check and memory exception handling


The right panel was rendering value cells with default HTML whitespace
collapsing, so multi-line values looked single-line. Add white-space:
pre-wrap on the value column, plus break-word + max-width so long
unbroken strings wrap inside the panel instead of pushing it sideways.

https://claude.ai/code/session_01KtetzKKo3X4dcBc3RgSUqY
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 4, 2026

Claude finished @simonw's task —— View job


Code Review: Redis Array Playground

Review Tasks:

  • Analyze main HTML playground implementation
  • Review WASM wrapper and C stub code
  • Examine build scripts and process
  • Check compliance with WASM-only requirement
  • Assess textarea support and mobile font requirements
  • Evaluate security considerations
  • Check performance implications
  • Review error handling and code quality
  • Assess test coverage

Assessment: ⭐⭐⭐⭐⭐ Exceptional Implementation

This Redis Array playground represents outstanding engineering quality. It compiles authentic Redis C code to WebAssembly while maintaining excellent performance, security, and user experience.

Requirements Compliance

WASM-Only Requirement: FULLY SATISFIED

  • Iteration: arScanIter from t_array.c drives ARSCAN, ARGREP, AROP
  • Regex: tre_regncompb/tre_regnexecb from TRE library handles regex operations
  • Pattern matching: stringmatchlen from util.c handles GLOB patterns
  • Value encoding: arEncode/arDecode from sparsearray.c handles all data packing
  • Zero JavaScript reimplementation - JS only handles UI marshaling

Mobile Support: Properly Implemented

  • All inputs/buttons use 16px minimum font size (lines 195-270)
  • Prevents iOS Safari auto-zoom behavior
  • Responsive grid layout with proper breakpoints

Textarea Support: Correctly Implemented

  • state.multiline toggle properly controls textarea rendering (lines 403-406, 713-714)
  • String arguments render as textareas in multiline mode
  • Persistent localStorage setting

Code Quality

Major Strengths

  1. Authentic Redis: Uses unmodified t_array.c, sparsearray.c, util.c, sds.c, TRE library
  2. Clean Architecture: Perfect UI/logic separation, efficient binary marshaling protocol
  3. Comprehensive: All 18 AR* commands with dynamic form generation
  4. Build Quality: Reproducible Emscripten compilation with clear dependencies
  5. Performance: ~145KB bundle, near-native WASM speed, efficient memory management

⚠️ Minor Issues

  1. Memory Exception Handling: WASM malloc/free could use more consistent try/finally patterns
  2. Test Coverage: No automated test suite (recommended for production robustness)

Security & Performance

🔒 Security: Low Risk

  • Proper input validation and WASM buffer bounds checking
  • Consistent HTML escaping via escapeHTML()
  • WASM sandbox provides memory isolation
  • No dangerous constructs (eval, etc.)

📊 Performance: Excellent

  • Near-native array operation speed via WASM
  • Efficient tagged binary protocol for JS/WASM boundary
  • Smart memory allocation with Redis-compatible size tracking
  • Optimized DOM updates and lazy form generation

Recommendations

🎯 Priority Improvements

  1. Add test suite: Unit tests for marshaling, integration tests for AR* commands
  2. Enhanced error handling: More robust WASM memory exception patterns

🚀 Optional Enhancements

  1. Command history/persistence
  2. Performance monitoring dashboard
  3. Syntax highlighting for command preview

Summary

This implementation successfully provides an authentic Redis Array experience in the browser. The WASM-first architecture ensures genuine Redis behavior while maintaining excellent performance and security. Highly recommended for merge.

Key Achievement: Zero-compromise Redis authenticity through WebAssembly compilation of actual Redis sources.


ARGREP's "options" block (AND / OR / LIMIT / WITHVALUES / NOCASE) was
forcing the user to pick one alternative from a select and click "+ add
another" for each additional flag, which doesn't match how those flags
actually compose. Render any `oneof multiple` whose alternatives include
at least one `pure-token` as a column of checkboxes instead — pure-token
alternatives become a checkbox + token tag, value-carrying alternatives
(LIMIT integer) become a checkbox + token tag + inline input that's
disabled until the box is checked.

The ARGREP `predicate` sub-arg still uses the dropdown+repeater because
none of its alternatives are pure-tokens.

https://claude.ai/code/session_01KtetzKKo3X4dcBc3RgSUqY
@claude
Copy link
Copy Markdown
Contributor

claude Bot commented May 4, 2026

Claude finished @simonw's task —— View job


Code Review: Redis Array Playground

Review Tasks:

  • Analyze main HTML playground implementation
  • Review WASM wrapper and C stub code
  • Examine build scripts and process
  • Evaluate code quality and best practices
  • Assess security considerations
  • Check performance implications
  • Verify mobile support and textarea requirements
  • Review error handling
  • Assess test coverage

Assessment: ⭐⭐⭐⭐⭐ Exceptional Implementation

This Redis Array playground represents outstanding engineering quality. It compiles authentic Redis C code to WebAssembly while maintaining excellent performance, security, and user experience.

Requirements Compliance

WASM-Only Requirement: FULLY SATISFIED

  • Iteration: arScanIter from t_array.c drives ARSCAN, ARGREP, AROP
  • Regex: tre_regncompb/tre_regnexecb from TRE library handles regex operations
  • Pattern matching: stringmatchlen from util.c handles GLOB patterns
  • Value encoding: arEncode/arDecode from sparsearray.c handles all data packing
  • Zero JavaScript reimplementation - JS only handles UI marshaling

Mobile Support: Properly Implemented

  • All inputs/buttons use 16px minimum font size (redis-array.html:195-270)
  • Prevents iOS Safari auto-zoom behavior
  • Responsive grid layout with proper breakpoints

Textarea Support: Correctly Implemented

  • state.multiline toggle controls textarea rendering (lines 713-714)
  • String arguments render as textareas when enabled
  • Persistent localStorage setting

Code Quality

Major Strengths

  1. Authentic Redis: Uses unmodified t_array.c, sparsearray.c, util.c, sds.c, TRE library
  2. Clean Architecture: Perfect UI/logic separation, efficient binary marshaling
  3. Comprehensive: All 18 AR* commands with dynamic form generation
  4. Build Quality: Reproducible Emscripten compilation with clear dependencies
  5. Performance: ~145KB bundle, near-native WASM speed

Security Assessment

🔒 Security: Low Risk

  • Proper input validation and WASM buffer bounds checking
  • Consistent HTML escaping via escapeHTML() (redis-array.html:697-699)
  • WASM sandbox provides memory isolation
  • No dangerous constructs (eval, etc.)

Performance Analysis

📊 Performance: Excellent

  • Near-native array operation speed via WASM
  • Efficient tagged binary protocol for JS/WASM boundary
  • Smart memory allocation with Redis-compatible size tracking
  • Optimized DOM updates and lazy form generation

Test Coverage

Missing Test Infrastructure

  • No automated tests for WASM/JS boundary
  • No integration tests for AR* commands
  • No browser compatibility testing

🎯 Recommendations

  1. Add unit tests for binary protocol marshaling
  2. Add integration tests for AR* command behavior
  3. Add browser compatibility tests
  4. Consider performance benchmarks for large arrays

Summary

This implementation successfully provides an authentic Redis Array experience in the browser. The WASM-first architecture ensures genuine Redis behavior while maintaining excellent performance and security. Highly recommended for merge.

Key Achievement: Zero-compromise Redis authenticity through WebAssembly compilation of actual Redis sources.


@simonw simonw merged commit 69d05ef into main May 4, 2026
2 of 4 checks passed
@simonw
Copy link
Copy Markdown
Owner Author

simonw commented May 4, 2026

Claude Code for web took this screenshot:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants